package com.cskaoyan.day03.linked;

/**
 * @author stone
 * @date 2022/01/29 19:30
 */
public class MyArrayList<T> {
    private static final int INIT_CAPACITY = 10;
    private final int MAX_CAPACITY = Integer.MAX_VALUE - 8;
    private Object[] elements;
    private int size;

    public MyArrayList(){
        elements = new Object[INIT_CAPACITY];
    }
    public MyArrayList(int capacity){
        if (capacity < 1 || capacity > MAX_CAPACITY)throw new RuntimeException("capacity = "+ capacity);

        elements = new Object[capacity];
    }

    // 增删改查
    public boolean add(T value){
        if (value == null)throw new RuntimeException("参数为空");

        // 判断数组是否满
        if (elements.length == size){
            int newLen = getLen();
            grow(newLen);
        }
        // 有位置可以添加
        elements[size++] = value;
        return true;
    }
    // 扩容数组 : 旧数组里面存储的内容转移到新数组里面
    private void grow(int newLen) {
        Object [] newElements = new Object[newLen];

        for (int i = 0; i < elements.length; i++) {
            newElements[i] = elements[i];
        }
        elements = newElements;
    }

    private int getLen() {
        // 获取旧长度
        int oldLen = elements.length;
        //  获取一个新长度
        int newLen = (oldLen * 2);

        if (newLen < 0 || newLen > MAX_CAPACITY){
            newLen = MAX_CAPACITY;
        }

        if (oldLen == newLen) throw new RuntimeException("stack is full");

        return newLen;
    }

    public boolean remove(T value){
        if (isEmpty()) throw new RuntimeException("空");

        int tag = -1;
        for (int i = 0; i < size; i++) {
            if (elements[i].equals(value)){
                // 相等
                tag = i;
                break;
            }
        }

        // tag
        if (tag == -1){
            // 没有找到这个元素
            return false;
        }
        // 找到了: 把后面的元素前移
        for (int i = tag; i < size - 1; i++) {
            elements[i] = elements[i+1];
        }

        size--;
        return true;

    }

    public boolean contains(T value){
        if (isEmpty()) throw new RuntimeException("空！");

        for (int i = 0; i < size; i++) {
            if (elements[i].equals(value)){
                // 相等
                return true;
            }
        }
        return false;
    }

    public boolean set(T origin , T value){
        if (isEmpty()) throw new RuntimeException("空");

        for (int i = 0; i < size; i++) {
            if (elements[i].equals(origin)){
                // 相等
                elements[i] = value;
                return true;
            }
        }
        return false;
    }

    // ------------------------------------------------------
    // 根据下标的: 增删改查
    public boolean add(int index , T value){
        if (index < 0 || index > size) throw new RuntimeException("index = "+ index);
        if (value == null) throw new NullPointerException();

        // 是否需要扩容
        if (size == elements.length){
            int newLen = getLen();
            grow(newLen);
        }

        // 是可以添加, 有空位置:
        // 从后向前一动需要一动的元素
        for (int i = size - 1; i >= index ; i--) {
            elements[i + 1] = elements[i];
        }

        elements[index] = value;
        size++;
        return true;
    }

    // 根据下标删除
    public T remove(int index){
        if (index < 0 || index > size-1) throw new RuntimeException("index = "+ index );

        T value = (T)elements[index];

        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }

        size--;
        return value;
    }

    // 根据下标查找
    public T get(int index){
        if (index < 0 || index > size-1) throw new RuntimeException("index = "+ index );

        return (T)elements[index];
    }

    // 根据下标替换
    public T set(int index, T value){
        if (index < 0 || index > size-1) throw new RuntimeException("index = "+ index );

        T oldValue = (T)elements[index];
        elements[index] = value;

        return oldValue;
    }


    public boolean isEmpty(){
        return size == 0;
    }
    public int size(){
        return size;
    }


    public void show() {
        if (isEmpty()) {
            System.out.println("空");
            return;
        }
        for (int i = 0; i < size; i++) {
            System.out.print( elements[i] + "-->");
        }
        System.out.println();

    }
}

